package com.bocloud.cmp.service.resource;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.dao.CloudVendorDao;
import com.bocloud.cmp.dao.HostSystemDao;
import com.bocloud.cmp.dao.NetworkCardDao;
import com.bocloud.cmp.dao.VdcDao;
import com.bocloud.cmp.driver.providers.intf.VdcProvider;
import com.bocloud.cmp.entity.resource.CloudVendor;
import com.bocloud.cmp.entity.resource.HostSystem;
import com.bocloud.cmp.entity.resource.NetworkCard;
import com.bocloud.cmp.entity.resource.Vdc;
import com.bocloud.cmp.interfaces.resource.VdcService;
import com.bocloud.cmp.model.VdcBean;
import com.bocloud.common.enums.BaseStatus;
import com.bocloud.common.model.BsmResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.Sign;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.common.utils.KeyGenerator;
import com.bocloud.coordinator.harmony.HarmonyLock;
import com.bocloud.coordinator.harmony.LockFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Service("vdcService")
public class VdcServiceImpl implements VdcService {

	private static final Logger logger = LoggerFactory.getLogger(VdcServiceImpl.class);
	@Autowired
	private VdcDao vdcDao;
	@Autowired
	private HostSystemDao hostSystemDao;
	@Autowired
	private NetworkCardDao networkCardDao;
	@Autowired
	private CloudVendorDao cloudVendorDao;
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private VdcProvider vdcProvider;

	@Override
	public BsmResult list(int page, int rows, List<Param> params, Map<String, String> sorter, Boolean simple) {
		GridBean gridBean = null;
		try {
			if (null == params) {
				params = Lists.newArrayList();
			}
			if (null == sorter) {
				sorter = Maps.newHashMap();
			}
			sorter.put("gmtCreate", Common.ONE);
			int total = this.vdcDao.count(params);
			if (simple) {
				List<SimpleBean> beans = this.vdcDao.list(params, sorter);
				gridBean = new GridBean(1, 1, total, beans);
			} else {
				Long vendorId = null;
				for (Param param : params) {
					if (param.getSign() == Sign.EQ) {
						for (String key : param.getParam().keySet()) {
							if (key.equals("vendorId") && !StringUtils.isEmpty(param.getParam().get(key).toString())) {
								vendorId = Long.valueOf(param.getParam().get(key).toString());
								break;
							}
						}
					}
				}
				// 获取实时的数据中心的资源使用量
				List<Vdc> allVdcs = Lists.newArrayList();
				if (null != vendorId) {
					CloudVendor vendor = cloudVendorDao.query(vendorId);
					if (null != vendor) {
						BsmResult result = vdcProvider.list(vendor.getUuid());
						if (null != result.getData()) {
							String content = JSONObject.toJSONString(result.getData());
							allVdcs.addAll(JSONObject.parseArray(content, Vdc.class));
						}
					}
				}

				Map<String, Vdc> vdcMap = Maps.newHashMap();
				for (Vdc vdc : allVdcs) {
					vdcMap.put(vdc.getVdcVal(), vdc);
				}

				// 数据库和实时情况进行比较，如果存在，则显示实时的情况
				List<Vdc> list = this.vdcDao.list(page, rows, params, sorter);
				for (Vdc vdc : list) {
					if (vdcMap.containsKey(vdc.getVdcVal())) {
						Vdc newVdc = vdcMap.get(vdc.getVdcVal());
						vdc.setCpuTotal(newVdc.getCpuTotal());
						vdc.setCpuUsed(newVdc.getCpuUsed());
						vdc.setMemTotal(newVdc.getMemTotal());
						vdc.setMemUsed(newVdc.getMemUsed());
						vdc.setDiskTotal(newVdc.getDiskTotal());
						vdc.setDiskUsed(newVdc.getDiskUsed());
					}
				}

				gridBean = GridHelper.getBean(page, rows, total, list);
			}
			return new BsmResult(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Query vdc list fail:", e);
			return new BsmResult(false, "查询失败");
		}
	}

	@Override
	public BsmResult create(Vdc vdc) {
		try {
			vdc.setStatus(BaseStatus.NORMAL.name());
			if (null == vdc.getUuid()) {
				vdc.setUuid(KeyGenerator.uuid());
			}
			vdcDao.save(vdc);
		} catch (Exception e) {
			logger.error("Create vdc fail:", e);
			return new BsmResult(false, "添加失败");
		}
		return new BsmResult(true, vdc, "添加成功");
	}

	@Override
	public BsmResult modify(VdcBean bean, Long userId) {
		String path = Vdc.class.getSimpleName() + "_" + bean.getId();
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时");
			}
			Vdc vdc = this.vdcDao.query(bean.getId());
			if (null == vdc) {
				logger.warn("Vdc does not exist!");
				return new BsmResult(false, "数据不存在");
			}
			BeanUtils.copyProperties(bean, vdc);
			vdc.setMenderId(userId);
			this.vdcDao.update(vdc);
			return new BsmResult(true, "修改成功");
		} catch (Exception e) {
			logger.error("Modify vdc fail:", e);
			return new BsmResult(false, "修改失败");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult remove(Long id, Long userId) {
		String path = Vdc.class.getSimpleName() + "_" + id;
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时");
			}
			Vdc object = this.vdcDao.query(id);
			if (null == object) {
				logger.warn("Vdc does not exist!");
				return new BsmResult(false, "数据不存在");
			}
			this.vdcDao.remove(id, userId);
			return new BsmResult(true, "删除成功");
		} catch (Exception e) {
			logger.error("Remove vdc error:", e);
			return new BsmResult(false, "删除失败");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult detail(Long id) {
		try {
			Vdc vdc = this.vdcDao.query(id);
			if (null == vdc) {
				return new BsmResult(false, "数据不存在");
			}
			return new BsmResult(true, vdc, "查询详情成功");
		} catch (Exception e) {
			logger.error("Get vdc error：", e);
			return new BsmResult(false, "查询详情失败");
		}
	}

	@Override
	public BsmResult listHost(Long id) {
		try {
			List<HostSystem> hosts = this.hostSystemDao.listByVdc(id);
			List<HostSystem> list = Lists.newArrayList();
			for (HostSystem host : hosts) {
				List<NetworkCard> cards = Lists.newArrayList();
				List<NetworkCard> netCards = networkCardDao.listByHost(host.getId(), "PM");
				for (NetworkCard card : netCards) {
					if (null != card.getUsed() && !card.getUsed()) {
						cards.add(card);
					}
				}
				if (!cards.isEmpty()) {
					host.setNetcards(cards);
					list.add(host);
				}
			}
			return new BsmResult(true, list, "查询详情成功");
		} catch (Exception e) {
			logger.error("List host by vdc error:", e);
			return new BsmResult(false, "查询失败");
		}
	}

}
